package com.WheresMyCar;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class Mapa extends MapActivity implements LocationListener,
		OnClickListener {
	private MapView mapView;
	private MyLocationOverlay mlo;
	private GeoPoint ultimaPosicaoDoCarroSalva;
	private List<Overlay> mapOverlays;
	private Drawable drawable;
	private Imagem itemizedOverlay;
	private BancoDeDadosSQL sqLite = new BancoDeDadosSQL();

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setTitle("Take me to my car");
		setContentView(R.layout.mapa);

		ativaCaracteristicasNoMapa();
		mlo = new MyLocationOverlay(this, mapView);
		makeUseOfNewLocation();
		mapOverlays = mapView.getOverlays();
		drawable = this.getResources().getDrawable(R.drawable.marcador);
		itemizedOverlay = new Imagem(drawable);

		alocaImagemNosPontosDoBD();
		zoomMaximo();
		adicionaBotoesNoMapa();
	}

	public void abreOuCriaBancoDeDados() {
		try {

			sqLite.bancoDeDados = openOrCreateDatabase("ArmazenaPontos",
					MODE_WORLD_READABLE, null);

			String sql = "CREATE TABLE IF NOT EXISTS pontos (id INTEGER PRIMARY KEY,latitude TEXT,longitude TEXT)";
			sqLite.bancoDeDados.execSQL(sql);
		} catch (Exception erro) {
			erro.getMessage();
		}
	}

	private void adicionaBotoesNoMapa() {
		View saveButton = findViewById(R.id.save_button);
		saveButton.setOnClickListener(this);

		View myPlaceButton = findViewById(R.id.myPlace_button);
		myPlaceButton.setOnClickListener(this);

		View takeMeToItButton = findViewById(R.id.takeMeToIt_button);
		takeMeToItButton.setOnClickListener(this);
	}

	private void ativaCaracteristicasNoMapa() {
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setSatellite(true);
		mapView.setBuiltInZoomControls(true);
	}

	private void zoomMaximo() {
		MapController mc = mapView.getController();
		mc.setZoom(mapView.getMaxZoomLevel()-2);
	}

	private void alocaImagemNosPontosDoBD() {
		abreOuCriaBancoDeDados();
		boolean temAlgoNoBD = false;
		if (sqLite.bancoDeDados != null) {
			sqLite.cursor = sqLite.bancoDeDados.query(true, "pontos",
					new String[] { "id", "latitude", "longitude" }, null, null,
					null, null, null, null);
			ArrayList<String> result = new ArrayList<String>();
			sqLite.cursor.moveToFirst();
			int i = 0;
			while (sqLite.cursor.moveToNext()) {
				result.add(sqLite.cursor.getString(sqLite.cursor
						.getColumnIndex("latitude")));
				result.add(sqLite.cursor.getString(sqLite.cursor
						.getColumnIndex("longitude")));

				if (sqLite.cursor.isLast()) {
					itemizedOverlay.addOverlay(new OverlayItem(new GeoPoint(
							Integer.valueOf(result.get(i)), Integer
									.valueOf(result.get(i + 1))), "", ""));
					ultimaPosicaoDoCarroSalva = new GeoPoint(Integer
							.valueOf(result.get(i)), Integer.valueOf(result
							.get(i + 1)));
					temAlgoNoBD = true;
				}
				i = i + 2;

			}
			if (temAlgoNoBD == true) {
				mapOverlays.add(itemizedOverlay);
			} else if (temAlgoNoBD != true) {
				ultimaPosicaoDoCarroSalva = new GeoPoint(1, 1);
				sqLite.inserirBancoDeDados(ultimaPosicaoDoCarroSalva);
			}
		}

		else {
			ultimaPosicaoDoCarroSalva = new GeoPoint(1, 1);
			sqLite.inserirBancoDeDados(ultimaPosicaoDoCarroSalva);

		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.tipo_visao:
			openVisaoDialog();
			return true;
		case R.id.about:
			Intent aboutIntent = new Intent(this, About.class);
			startActivity(aboutIntent);
			return true;
			// More items go here (if any) ...
		}
		return false;
	}

	private void openVisaoDialog() {
		new AlertDialog.Builder(this).setTitle(R.string.tipo_visao_title)
				.setItems(R.array.tipoVisao,
						new DialogInterface.OnClickListener() {
							public void onClick(
									DialogInterface dialoginterface, int i) {
								trocaVisao(i);
							}
						}).show();

	}

	private void trocaVisao(int i) {
		if (i == 0) {
			mapView.setSatellite(false);
		} else if (i == 1) {
			mapView.setSatellite(true);
		}
	}

	public void onLocationChanged(Location location) {
		makeUseOfNewLocation();

	}

	private void makeUseOfNewLocation() {
		mlo.enableMyLocation();
		mapView.getOverlays().add(mlo);

	}

	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	public void onProviderEnabled(String provider) {
	}

	public void onProviderDisabled(String provider) {
	}

	private void DrawPath(GeoPoint src, GeoPoint dest, int color,
			MapView mMapView01) {
		// connect to map web service
		StringBuilder urlString = new StringBuilder();
		urlString.append("http://maps.google.com/maps?f=d&hl=en");
		urlString.append("&saddr=");// from
		urlString.append(Double.toString((double) src.getLatitudeE6() / 1.0E6));
		urlString.append(",");
		urlString
				.append(Double.toString((double) src.getLongitudeE6() / 1.0E6));
		urlString.append("&daddr=");// to
		urlString
				.append(Double.toString((double) dest.getLatitudeE6() / 1.0E6));
		urlString.append(",");
		urlString.append(Double
				.toString((double) dest.getLongitudeE6() / 1.0E6));
		urlString.append("&ie=UTF8&0&om=0&output=kml");
		Log.d("xxx", "URL=" + urlString.toString());
		// get the kml (XML) doc. And parse it to get the coordinates(direction
		// route).
		Document doc = null;
		HttpURLConnection urlConnection = null;
		URL url = null;
		try {
			url = new URL(urlString.toString());
			urlConnection = (HttpURLConnection) url.openConnection();
			urlConnection.setRequestMethod("GET");
			urlConnection.setDoOutput(true);
			urlConnection.setDoInput(true);
			urlConnection.connect();

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			doc = db.parse(urlConnection.getInputStream());

			if (doc.getElementsByTagName("GeometryCollection").getLength() > 0) {
				// String path =
				// doc.getElementsByTagName("GeometryCollection").item(0).getFirstChild().getFirstChild().getNodeName();
				String path = doc.getElementsByTagName("GeometryCollection")
						.item(0).getFirstChild().getFirstChild()
						.getFirstChild().getNodeValue();
				Log.d("xxx", "path=" + path);
				String[] pairs = path.split(" ");
				String[] lngLat = pairs[0].split(","); // lngLat[0]=longitude
				// lngLat[1]=latitude
				// lngLat[2]=height
				// src
				GeoPoint startGP = new GeoPoint((int) (Double
						.parseDouble(lngLat[1]) * 1E6), (int) (Double
						.parseDouble(lngLat[0]) * 1E6));
				mMapView01.getOverlays()
						.add(new MyOverlay(startGP, startGP, 1));
				GeoPoint gp1;
				GeoPoint gp2 = startGP;
				for (int i = 1; i < pairs.length; i++) // the last one would be
				// crash
				{
					lngLat = pairs[i].split(",");
					gp1 = gp2;
					// watch out! For GeoPoint, first:latitude, second:longitude
					gp2 = new GeoPoint(
							(int) (Double.parseDouble(lngLat[1]) * 1E6),
							(int) (Double.parseDouble(lngLat[0]) * 1E6));
					mMapView01.getOverlays().add(
							new MyOverlay(gp1, gp2, 2, color));
					Log.d("xxx", "pair:" + pairs[i]);
				}
				mMapView01.getOverlays().add(new MyOverlay(dest, dest, 3)); // use
				// the
				// default
				// color
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onClick(View v) {
		try {
			switch (v.getId()) {
			case R.id.save_button:
				ultimaPosicaoDoCarroSalva = mlo.getMyLocation();
				OverlayItem overlayitem = new OverlayItem(
						ultimaPosicaoDoCarroSalva, "", "");

				itemizedOverlay.addOverlay(overlayitem);

				mapOverlays.add(itemizedOverlay);
				sqLite.inserirBancoDeDados(ultimaPosicaoDoCarroSalva);

				break;
			case R.id.takeMeToIt_button:
				if (ultimaPosicaoDoCarroSalva == null) {
					break;
				}
				GeoPoint srcGeoPoint = mlo.getMyLocation();
				GeoPoint destGeoPoint = ultimaPosicaoDoCarroSalva;

				DrawPath(srcGeoPoint, destGeoPoint, Color.GREEN, mapView);

				mapView.getController().animateTo(srcGeoPoint);

				break;
			case R.id.myPlace_button:
				mapView.getController().animateTo(mlo.getMyLocation());
				zoomMaximo();
				break;
			}
		} catch (Exception e) {
			Intent esperaIntent = new Intent(this, PontoNaoCarregado.class);
			startActivity(esperaIntent);
		}
	}
}
